#include "mvc/view/analisis_dialog.h"
#include "ui_analisis_dialog.h"

#include <iostream>

Analisis_dialog::Analisis_dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Analisis_dialog)
{
    ui->setupUi(this);
    connect_buttons();

    retranslateUi();
}

Analisis_dialog::~Analisis_dialog()
{
    delete ui;
}

/**
 * @brief Analisis_dialog::drawAirfoil
 * @param customPlot
 */
void Analisis_dialog::drawAirfoil(QCustomPlot *customPlot)
{
//    customPlot->setInteraction(QCustomPlot::iSelectPlottables);
//    QCPCurve *curve = new QCPCurve(customPlot->xAxis, customPlot->yAxis);

    QPair<double, double> x_min_max = get_min_max(domain_values);
    QPair<double, double> y_min_max = get_min_max(image_values);

    customPlot->xAxis->setRange(x_min_max.first, x_min_max.second);
    customPlot->yAxis->setRange(y_min_max.first, y_min_max.second);

//    curve->setData(domain_values, image_values);
//    curve->setPen(QPen(Qt::blue));

    customPlot->addGraph(customPlot->xAxis, customPlot->yAxis);
    customPlot->graph(0)->setData(domain_values, image_values);
    customPlot->graph(0)->setPen(QPen(Qt::blue));
    customPlot->graph(0)->setLineStyle(QCPGraph::lsLine);
    customPlot->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 5));
    customPlot->graph(0)->setName("Left maxwell function");

//    scustomPlot->setupFullAxesBox();
    customPlot->rescaleAxes();
    customPlot->replot();
//    curve->clearData();
}

/**
 * @brief Analisis_dialog::set_domain_variable
 * @param domain_variable
 */
void Analisis_dialog::set_domain_variable(const QString &domain_variable)
{
    domain = domain_variable;

    ui->x_variable->setText(domain);
}

/**
 * @brief Analisis_dialog::set_image_variables
 * @param image_variables
 */
void Analisis_dialog::set_image_variables(const QVector<QString> &image_variables)
{
    image = image_variables;

    typedef QVector<QString>::const_iterator it;

    for(it c_coefficient = image_variables.begin(); c_coefficient != image_variables.end(); c_coefficient++)
        ui->coefficients->addItem(*c_coefficient);
}

/**
 * @brief Analisis_dialog::add_values
 * @param x_value
 * @param y_values
 */
void Analisis_dialog::add_values(double x_value, const QMap<QString, doublevalues> &y_values)
{
    Q_ASSERT(domain_values.size() == image_map.size());

    domain_values.push_back(x_value);
    image_map.push_back(y_values);

    int n_steps;

#if(QT_VERSION <= QT_VERSION_CHECK(5, 2, 0))
    n_steps = (y_values.begin()).value().count();
#elif(QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
    n_steps = y_values.first().count();
#endif

    int c_steps = ui->steps->count();

    for(int i = c_steps; i < n_steps; i++)
        ui->steps->addItem(QString::number(i + 1));
}

//-----------------------------------------------------------------
//                   Private Slots
//-----------------------------------------------------------------

/**
 * @brief Analisis_dialog::image_value_selected
 * @param y_value
 */
void Analisis_dialog::image_value_selected(const QString &y_value)
{
//    std::cout << "TODO: Analisis_dialog::image_value_selected " << y_value.toStdString() << std::endl;

    image_values.clear();

    for(int i = 0; i < domain_values.size(); i++)
    {
        QMap<QString, doublevalues> c_map = image_map.at(i);

        QVector<double> values = c_map[y_value];

        int c_step = ui->steps->currentText().toInt() - 1;

        if(values.size() > c_step)
            image_values.push_back(values.at(c_step));
        else
            image_values.push_back(0.0);
    }

    drawAirfoil(ui->customPlot);
}

/**
 * @brief Analisis_dialog::time_value_selected
 * @param time_value
 */
void Analisis_dialog::time_value_selected(const QString &time_value)
{
//    std::cout << "TODO: Analisis_dialog::time_value_selected " << time_value.toStdString() << std::endl;

    image_values.clear();

    for(int i = 0; i < domain_values.size(); i++)
    {
        QMap<QString, doublevalues> c_map = image_map.at(i);

        QVector<double> values = c_map[ui->coefficients->currentText()];

        int c_step = ui->steps->currentText().toInt() - 1;

        if(values.size() > c_step)
            image_values.push_back(values.at(c_step));
        else
            image_values.push_back(0.0);
    }

    drawAirfoil(ui->customPlot);
}

/**
 * @brief Analisis_dialog::connect_buttons
 */
void Analisis_dialog:: connect_buttons()
{
    connect(ui->close_button, SIGNAL(clicked()), this, SLOT(close_button_pressed())) ;
    connect(ui->coefficients, SIGNAL(activated(QString)), this, SLOT(image_value_selected(QString)));
    connect(ui->steps, SIGNAL(activated(QString)), this, SLOT(time_value_selected(QString)));
}

/**
 * @brief Analisis_dialog::close_button_pressed
 */
void Analisis_dialog:: close_button_pressed()
{
    this->close();
}

/**
 * @brief Analisis_dialog::retranslateUi
 */
void Analisis_dialog:: retranslateUi()
{
    setWindowTitle(tr("Analysis"));
    ui->retranslateUi(this);
}

//----------------------------------------------------------
//               Private Functions
//----------------------------------------------------------

/**
 * @brief Analisis_dialog::get_min_max
 * @param vector
 * @return
 */
QPair<double, double> Analisis_dialog::get_min_max(const QVector<double> &vector)
{
    QPair<double, double> result;

    double min = 99999, max = -99999;

    for(int i = 0; i < vector.size(); i++)
    {
        double c_value = vector.at(i);

        if(c_value > max)
            max = c_value;

        if(c_value < min)
            min = c_value;
    }

    result.first = min;
    result.second = max;

    return result;
}
